--- title: "05-Java 接口与抽象类对比" aliases: - "Java 接口与抽象类对比" created: 2025-12-25 --- # Java 接口与抽象类对比 ## **一、概念总览** ### **1.1 什么是抽象类和接口** ```drawio ``` ### **1.2 类比理解** ```drawio ``` ## **二、基本语法** ### **2.1 抽象类语法** ```java /** * 抽象类定义 */ public abstract class Animal { // ===== 1. 可以有各种访问修饰符的属性 ===== private String name; // 私有属性 protected int age; // 受保护属性 public static int count = 0; // 静态属性 // ===== 2. 可以有构造方法 ===== public Animal() { count++; } public Animal(String name, int age) { this.name = name; this.age = age; count++; } // ===== 3. 可以有具体方法(有方法体)===== public void sleep() { System.out.println(name + " 正在睡觉"); } // ===== 4. 可以有抽象方法(无方法体)===== public abstract void makeSound(); // 子类必须实现 public abstract void eat(); // 子类必须实现 // ===== 5. Getter/Setter ===== public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` ### **2.2 接口语法** ```java /** * 接口定义 */ public interface Flyable { // ===== 1. 常量(默认 public static final)===== int MAX_HEIGHT = 10000; // 等价于 public static final int MAX_HEIGHT = 10000; // ===== 2. 抽象方法(默认 public abstract)===== void fly(); // 等价于 public abstract void fly(); void land(); // ===== 3. 默认方法(Java 8+)===== default void glide() { System.out.println("滑翔中..."); } // ===== 4. 静态方法(Java 8+)===== static void showInfo() { System.out.println("这是飞行接口"); } // ===== 5. 私有方法(Java 9+)===== private void prepare() { System.out.println("准备飞行"); } } ``` ### **2.3 语法对比表** | **语法元素** | **抽象类** | **接口** | | --- | --- | --- | | 关键字 | `abstract class` | `interface` | | 继承/实现 | `extends` | `implements` | | 构造方法 | ✅ 可以有 | ❌ 不能有 | | 普通属性 | ✅ 任意修饰符 | ❌ 只能是常量 | | 静态属性 | ✅ 可以有 | ✅ 默认 `public static final` | | 具体方法 | ✅ 可以有 | ✅ `default`/`static` 方法 | | 抽象方法 | ✅ 可以有 | ✅ 默认就是抽象的 | | 代码块 | ✅ 可以有 | ❌ 不能有 | ## **三、共同点** ### **3.1 共同点一览** ```drawio ``` ## **四、核心差异** ### **4.1 差异对比表** | **特性** | **抽象类 (Abstract Class)** | **接口 (Interface)** | | --- | --- | --- | | **设计目的** | 提供通用实现(模板) | 定义行为规范(契约) | | **继承/实现** | 单继承(只能 extends 一个) | 多实现(可 implements 多个) | | **成员变量** | 任意修饰符,可以是普通变量 | 只能是 `public static final` 常量 | | **构造方法** | ✅ 可以有 | ❌ 不能有 | | **方法实现** | 可以有具体方法 | Java 8 前只有抽象方法 | | **访问修饰符** | 任意(public/protected/private) | 方法默认 public | | **静态方法** | ✅ 可以有 | ✅ Java 8+ 可以有 | | **main 方法** | ✅ 可以有 | ✅ Java 8+ 可以有 | | **设计层面** | 代码复用(is-a 关系) | 能力扩展(can-do 关系) | --- ### **4.2 差异图解** ```drawio ``` ### **4.3 单继承 vs 多实现** ```java // ===== 抽象类:单继承 ===== abstract class Animal { } abstract class Machine { } // ❌ 编译错误:Java 不支持多继承 // class Robot extends Animal, Machine { } // ===== 接口:多实现 ===== interface Flyable { void fly(); } interface Swimmable { void swim(); } interface Runnable { void run(); } // ✅ 正确:可以实现多个接口 class Duck extends Animal implements Flyable, Swimmable { @Override public void fly() { System.out.println("鸭子飞"); } @Override public void swim() { System.out.println("鸭子游泳"); } } // ✅ 接口可以继承多个接口 interface Amphibious extends Flyable, Swimmable { void crawl(); // 额外的方法 } ``` **继承关系图**: ```drawio ``` ## **五、完整代码示例** ### **5.1 抽象类示例** ```java /** * 抽象类:鸟类 * 提供通用实现 + 定义抽象行为 */ public abstract class Bird { // ===== 属性(可以有任意类型)===== protected String name; protected String color; private int age; // ===== 构造方法 ===== public Bird() { System.out.println("Bird 构造方法执行"); } public Bird(String name, String color) { this.name = name; this.color = color; } // ===== 具体方法(通用实现)===== public void sleep() { System.out.println(name + " 正在睡觉 Zzz..."); } public void showInfo() { System.out.println("鸟名:" + name + ",颜色:" + color); } // ===== 抽象方法(子类必须实现)===== public abstract void sing(); // 不同鸟叫声不同 public abstract void move(); // 不同鸟移动方式不同 // ===== Getter/Setter ===== public String getName() { return name; } public void setName(String name) { this.name = name; } } /** * 具体类:麻雀 */ public class Sparrow extends Bird { public Sparrow(String name) { super(name, "灰褐色"); } @Override public void sing() { System.out.println(name + ":叽叽喳喳~"); } @Override public void move() { System.out.println(name + " 在天空飞翔"); } } /** * 具体类:企鹅 */ public class Penguin extends Bird { public Penguin(String name) { super(name, "黑白色"); } @Override public void sing() { System.out.println(name + ":嘎嘎嘎~"); } @Override public void move() { System.out.println(name + " 在地上摇摆行走"); // 企鹅不会飞 } } ``` ### **5.2 接口示例** ```java /** * 接口:飞行能力 */ public interface Flyable { // 常量 int MAX_ALTITUDE = 10000; // 最大飞行高度 // 抽象方法 void fly(); void land(); // 默认方法(Java 8+) default void glide() { System.out.println("滑翔中..."); } // 静态方法(Java 8+) static void showFlightRules() { System.out.println("飞行规则:注意安全!"); } } /** * 接口:游泳能力 */ public interface Swimmable { void swim(); default void dive() { System.out.println("潜水中..."); } } /** * 接口:可食用(标记接口) */ public interface Edible { String getHowToEat(); } ``` ### **5.3 综合使用示例** ```java /** * 野鸭类:继承抽象类 + 实现多个接口 */ public class WildDuck extends Bird implements Flyable, Swimmable, Edible { public WildDuck(String name) { super(name, "绿头色"); } // ===== 实现抽象类的抽象方法 ===== @Override public void sing() { System.out.println(name + ":嘎嘎嘎~"); } @Override public void move() { System.out.println(name + " 可以飞、游、走"); } // ===== 实现 Flyable 接口 ===== @Override public void fly() { System.out.println(name + " 展翅高飞,最高 " + MAX_ALTITUDE + " 米"); } @Override public void land() { System.out.println(name + " 平稳降落"); } // ===== 实现 Swimmable 接口 ===== @Override public void swim() { System.out.println(name + " 在水中畅游"); } // ===== 实现 Edible 接口 ===== @Override public String getHowToEat() { return name + " 可以烤着吃"; } } /** * 测试类 */ public class Main { public static void main(String[] args) { WildDuck duck = new WildDuck("唐老鸭"); // 调用继承的方法 duck.showInfo(); // 鸟名:唐老鸭,颜色:绿头色 duck.sleep(); // 唐老鸭 正在睡觉 Zzz... // 调用实现的方法 duck.fly(); // 唐老鸭 展翅高飞,最高 10000 米 duck.swim(); // 唐老鸭 在水中畅游 duck.sing(); // 唐老鸭:嘎嘎嘎~ // 调用默认方法 duck.glide(); // 滑翔中... duck.dive(); // 潜水中... // 调用静态方法 Flyable.showFlightRules(); // 飞行规则:注意安全! System.out.println(duck.getHowToEat()); // 唐老鸭 可以烤着吃 // ===== 多态使用 ===== System.out.println("\n===== 多态演示 ====="); Bird bird = duck; // 作为鸟 bird.sing(); Flyable flyer = duck; // 作为飞行者 flyer.fly(); Swimmable swimmer = duck; // 作为游泳者 swimmer.swim(); } } ``` **输出结果**: ``` Bird 构造方法执行 鸟名:唐老鸭,颜色:绿头色 唐老鸭 正在睡觉 Zzz... 唐老鸭 展翅高飞,最高 10000 米 唐老鸭 在水中畅游 唐老鸭:嘎嘎嘎~ 滑翔中... 潜水中... 飞行规则:注意安全! 唐老鸭 可以烤着吃 ===== 多态演示 ===== 唐老鸭:嘎嘎嘎~ 唐老鸭 展翅高飞,最高 10000 米 唐老鸭 在水中畅游 ``` ### **5.4 类关系图** ```drawio ``` ## **六、Java 8+ 接口新特性** ### **6.1 特性演进图** ```drawio ``` ### **6.2 默认方法详解** ```java /** * 默认方法示例 */ public interface Collection { // 抽象方法 int size(); // Java 8 默认方法:提供默认实现 default boolean isEmpty() { return size() == 0; // 基于抽象方法实现 } } /** * 实现类可以: * 1. 直接使用默认方法 * 2. 重写默认方法 */ public class MyList implements Collection { private int count = 0; @Override public int size() { return count; } // isEmpty() 直接继承,无需实现 // 也可以选择重写 // @Override // public boolean isEmpty() { // return count <= 0; // } } ``` ### **6.3 默认方法冲突解决** ```java interface A { default void hello() { System.out.println("Hello from A"); } } interface B { default void hello() { System.out.println("Hello from B"); } } // 实现类必须解决冲突 class C implements A, B { @Override public void hello() { // 方式1:自己实现 System.out.println("Hello from C"); // 方式2:选择调用某个接口的默认方法 // A.super.hello(); // 方式3:两个都调用 // A.super.hello(); // B.super.hello(); } } ``` **冲突解决规则**: ```drawio ``` ## **七、使用场景** ### **7.1 场景对比表** | **场景** | **选择** | **原因** | | --- | --- | --- | | 定义一组相关类的通用模板 | **抽象类** | 可共享代码和状态 | | 定义不相关类的共同行为 | **接口** | 无继承关系也可实现 | | 需要多重继承能力 | **接口** | 类只能单继承,接口可多实现 | | 需要定义常量 | **接口** | 接口常量默认 public static final | | 需要构造方法 | **抽象类** | 接口没有构造方法 | | 需要成员变量(非常量) | **抽象类** | 接口只能有常量 | | API 设计,需要向后兼容 | **接口+默认方法** | 可添加新方法不破坏实现类 | | 定义规范(契约) | **接口** | 接口天然就是契约 | --- ### **7.2 抽象类使用场景** ```drawio ``` ### **7.3 接口使用场景** ```drawio ``` ### **7.4 JDK 中的典型例子** | **类型** | **例子** | **说明** | | --- | --- | --- | | **抽象类** | `AbstractList` | List 的骨架实现,提供通用方法 | | | `AbstractMap` | Map 的骨架实现 | | | `InputStream` | 输入流基类 | | | `HttpServlet` | Servlet 模板类 | | **接口** | `List` / `Set` / `Map` | 集合规范 | | | `Comparable` | 比较能力 | | | `Serializable` | 序列化标记 | | | `Runnable` / `Callable` | 任务定义 | | | `Iterator` | 迭代器规范 | --- ### **7.5 选择决策流程图** ```drawio ``` ## **八、核心总结** ### **8.1 一句话总结** ```drawio ``` ### **8.2 速查对比表** | **对比维度** | **抽象类** | **接口** | | --- | --- | --- | | 关键字 | `abstract class` | `interface` | | 继承/实现 | 单继承 | 多实现 | | 成员变量 | 任意 | 只有常量 | | 构造方法 | ✅ 有 | ❌ 无 | | 方法类型 | 具体+抽象 | 抽象+default+static | | 设计理念 | 模板(is-a) | 规范(can-do) | | 典型场景 | 模板方法、共享代码 | 定义能力、解耦 | --- ### **8.3 记忆口诀** ```drawio ``` ```mermaid %%{init: { "theme": "base", "themeVariables": { "primaryColor": "#e3f2fd", "primaryTextColor": "#0d47a1", "primaryBorderColor": "#2196f3", "lineColor": "#546e7a", "fontSize": "14px", "tertiaryColor": "#fdfdfd" }, "flowchart": { "curve": "basis", "htmlLabels": true } }}%% graph TB %% 样式定义 classDef abstractStyle fill:#e3f2fd,stroke:#2196f3,stroke-width:2px,color:#0d47a1; classDef interfaceStyle fill:#f1f8e9,stroke:#4caf50,stroke-width:2px,color:#1b5e20; classDef selectStyle fill:#fff3e0,stroke:#ff9800,stroke-width:2px,color:#e65100; classDef titleStyle fill:#f5f5f5,stroke:#9e9e9e,stroke-width:1px,color:#333,font-weight:bold; MainTitle(["Java 抽象类与接口记忆口诀"]) subgraph AbstractGroup ["抽象类 (Abstract Class)"] A1["有构造,能存变量"] A2["单继承,可有具体"] A3["模板用,共享状态"] end subgraph InterfaceGroup ["接口 (Interface)"] I1["无构造,只常量"] I2["多实现,定规范"] I3["Java 8 后,有默认"] end subgraph StrategyGroup ["选择策略 (Decision Guide)"] S1{"场景选择"} S2["要模板/共享用抽象类"] S3["定规范/解耦用接口"] S4(["核心原则:优先接口,抽象补充"]) end %% 连接逻辑 MainTitle --> AbstractGroup MainTitle --> InterfaceGroup AbstractGroup ~~~ StrategyGroup InterfaceGroup ~~~ StrategyGroup S1 ==> S2 S1 ==> S3 S2 --> S4 S3 --> S4 %% 应用样式 class AbstractGroup,A1,A2,A3 abstractStyle; class InterfaceGroup,I1,I2,I3 interfaceStyle; class StrategyGroup,S1,S2,S3,S4 selectStyle; class MainTitle titleStyle; ```